package model;

import java.util.Date;
import java.util.List;
import java.util.ArrayList;

/**
 * 
 *Esta clase contiene la estrutura de datos y metodos necesarios para administrar un CFP.
 */

public class CFP {

	private String nombre;
	private Usuario autor;
	private List<Trabajo> listaDeTrabajos = new ArrayList<Trabajo>();
	private List<Usuario> listaDeAutores = new ArrayList<Usuario>();
	private List<Usuario> listaDeRevisores = new ArrayList<Usuario>();
	private List<String> areasDeInteres = new ArrayList<String>();
	private Date fechaTopeDeRecepcion;
	private Date fechaTopeDeRevision;
	private Temporizador temporizador;


	
	/**
	 * CONSTRUCTOR
	 * @param autor recibe un Usuario
	 * @param nombre recibe un String que es el nombre del CFP
	 * @param areasInteres recibe una lista de Strings que representan las areas a las que aplica el CFP
	 * @param fechaTopeRecepcion recibe un Date
	 * @param fechaTopeRevision recibe un Date
	 * @param revisores recibe una lista de Usuarios, los cuales seran los revisores del CFP
	 */
	public CFP(Usuario autor, String nombre, List<String> areasInteres,
			Date fechaTopeRecepcion, Date fechaTopeRevision, List<Usuario> revisores) {

		this.setAutor(autor);
		this.getAreasDeInteres().addAll(areasInteres);
		this.setNombre(nombre);
		this.setFechaTopeDeRecepcion(fechaTopeRecepcion);
		this.setFechaTopeDeRevision(fechaTopeRevision);
		this.crearRevisores(revisores);
	}

	


	public Temporizador getTemporizador() {
		return temporizador;
	}
	
	protected void setTemporizador(Temporizador temp) {
		this.temporizador = temp;
	}
	
	public String getNombre() {
		return nombre;
	}
	
	private void setNombre(String nombre){
		this.nombre = nombre;
	}

	public Usuario getAutor() {
		return autor;
	}
	
	private void setAutor(Usuario usuario){
		this.autor = usuario;
	}

	public List<Trabajo> getTrabajos() {
		return listaDeTrabajos;
	}
	
	public void setTrabajos(List<Trabajo>trabajos){
		this.listaDeTrabajos = trabajos;
	}

	public List<Usuario> getListaDeAutores() {
		return listaDeAutores;
	}

	public List<Usuario> getListaDeRevisores() {
		return listaDeRevisores;
	}

	public List<String> getAreasDeInteres() {
		return areasDeInteres;
	}

	public Date getFechaTopeDeRecepcion() {
		return fechaTopeDeRecepcion;
	}
	
	void setFechaTopeDeRecepcion(Date dia){
		this.fechaTopeDeRecepcion = dia;
	}

	public Date getFechaTopeDeRevision() {
		return fechaTopeDeRevision;
	}
	
	private void setFechaTopeDeRevision(Date dia){
		this.fechaTopeDeRevision = dia;
	}

	
	/**
	 * Activa el Temporizador que disparara la asignacion automatica de revisores para un CFP determinado
	 * @param fechaTopeRecepcion Date
	 * @param sistema SistemaWeb, al cual necesita para llegada la fechaTope pueda disparar la asignacion
	 * @param cfp CFP
	 */
	protected void activarTemporizador(Date fechaTopeRecepcion,
			SistemaWeb sistema, CFP cfp) {

		this.temporizador = new Temporizador(fechaTopeRecepcion, sistema, cfp);
		this.temporizador.activar();
	}
	
	/**
	 * 
	 * @return true si ya paso la fechaDe Envio, false en caso contrario
	 */
	 protected boolean caducoFechaDeEnvío(){
		
		Date fechaActual = new Date();
		return this.getFechaTopeDeRecepcion().before(fechaActual);
	}

	 /**
	  * chequea si el usuario puede enviar trabajos al CFP
	  * retorna true si puede, false en caso contrario
	  * @param usuario
	  * @return
	  */
	protected boolean puedeEnviarTps(Usuario usuario){
		return ! this.listaDeRevisores.contains(usuario);
	}
	
	
	
	/**
	 * Agrega un trabajo al Usuario y crea el rol de Autor para el mismo
	 * @param trabajo
	 * @param usuario
	 */
	public void agregarTrabajo(Trabajo trabajo, Usuario usuario){
		
		if(this.puedeEnviarTps(usuario)){
		this.listaDeTrabajos.add(trabajo);
		
		if(this.noEsAutorEnEsteCFP(usuario)){
			
			this.nuevoAutor(usuario);
		}
		
		usuario.agregarTrabajo(trabajo, this);
		}
		
	}
	
	/**
	 * crea el rol de revisores para cada usuario de la lista que recibe como parametro
	 * @param revisores List<Usuario>
	 */
	private void crearRevisores(List<Usuario> revisores) {
	
		for (Usuario usuario : revisores) {
			
			Rol rol = new Rol("revisor");
			this.getListaDeRevisores().add(usuario);
			usuario.crearAsignacion(this.getNombre(), rol);
		}
		
	}
	
	/**
	 * Crea el rol de autor para el Usuario que recibe como parametro
	 * @param usuario
	 */
	private void nuevoAutor(Usuario usuario){
		Rol autor = new Rol("autor");
		this.agregarAutor(usuario);
		usuario.crearAsignacion(this.getNombre(), autor);
	}
	
	/**
	 * retorna true si el usuario que se pasa como parametro no es Autor del CFP, 
	 * false en caso contrario
	 * @param usuario
	 * @return
	 */
	private boolean noEsAutorEnEsteCFP(Usuario usuario){
		return ! this.getListaDeAutores().contains(usuario);
	}

	/**
	 * agrega un usuario a las lista de autores
	 * @param autor recibe un Usuario como parametro
	 */
	private void agregarAutor(Usuario autor) {

		this.listaDeAutores.add(autor);
	}

}
